package top.lishuoboy.hibernate.validator.dto;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <h1>分页参数</h1>
 * <p>
 * 所有字段名字与MP的Page对象保持一致。其中orders的字段类型用String，与PageHelper保持一致
 * <p>
 * 2024-10-25
 *
 * @author lishuoboy
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@Accessors(chain = true)
@ApiModel(description = "分页请求")
public class PageReq<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /** 查询条件 */
    @Valid
    @ApiModelProperty(value = "查询条件", position = 0)
    private T condition;
    /** 当前页，默认1 */
    @ApiModelProperty(value = "当前页，默认1", position = 1)
    @Min(1)
    private Integer current = 1;
    /** 每页显示条数，默认10。等于0时，不查询记录；小于0时，查询全部结果。查询全部结果：MybatisPlus需设置为负数，PageHelper需设置pageSizeZero=true（在yml配置文件中开启） */
    @ApiModelProperty(value = "每页显示条数，默认10", position = 2)
    private Integer size = 10;
    /** 排序字段们。格式：id,name desc,email */
    @ApiModelProperty(value = "排序字段们", example = "id desc, name, email", position = 3)
    private String orders;

    /** 转 PageHelper 的 分页 对象 */
    public Map<String, Object> toPageHelper() {
        // PageHelper不从对象里获取count。所以不在这里.put("count", this.searchCount)
        return MapUtil.<String, Object>builder().put("pageNum", this.current).put("pageSize", size < 0 ? 0 : this.size).put("orderBy", this.orders).build();
    }

    /** 转 MybatisPlus 的 Page 对象 */
    public <T> Page<T> toPage() {
        return new Page<T>(current, size).addOrder(toOrderItemList());
    }

    /** 将 orders 转为 orderItemList。字段名字驼峰转下划线。public方法名字不能以get开头，否则会显示在swagger文档 */
    private List<OrderItem> toOrderItemList() {
        List<OrderItem> orderItemList = new ArrayList<>();
        if (orders == null) {
            return orderItemList;
        }
        orders = StrUtil.toUnderlineCase(orders);
        String[] orderByArr = orders.split(StrPool.COMMA);
        StrUtil.trim(orderByArr);
        for (String orderBy : orderByArr) {
            if (StrUtil.isBlank(orderBy)) {
                continue;
            }
            if (StrUtil.endWithIgnoreCase(orderBy, "DESC")) {
                orderItemList.add(OrderItem.desc(StrUtil.subBefore(orderBy, StrPool.C_SPACE, false)));
            } else if (StrUtil.endWithIgnoreCase(orderBy, "ASC")) {
                orderItemList.add(OrderItem.asc(StrUtil.subBefore(orderBy, StrPool.C_SPACE, false)));
            } else {
                orderItemList.add(OrderItem.asc(orderBy));
            }
        }
        return orderItemList;
    }
}
